package nl.jjsoft.airlock.view.presenters
{
	import com.adobe.utils.StringUtil;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filesystem.File;
	
	import mx.controls.Alert;
	import mx.controls.CheckBox;
	
	import nl.jjsoft.airlock.AirLockConstants;
	import nl.jjsoft.airlock.controller.ILoginController;
	import nl.jjsoft.airlock.controller.SafeController;
	import nl.jjsoft.airlock.domain.Model;
	import nl.jjsoft.airlock.domain.Session;
	import nl.jjsoft.airlock.event.ApplicationEvent;
	import nl.jjsoft.airlock.utils.DbUtils;
	import nl.jjsoft.airlock.utils.ResourceFactory;
	import nl.jjsoft.airlock.view.Setup;
	
	public class SetupPresenter extends AbstractPresenter 
	{
		[Inject]
		public var loginController:ILoginController;
		
		[Inject]
		public var safeController:SafeController;
		
		[Inject]
		public var session:Session;
		
		[Inject]
		public var model:Model;
		
		[Inject]
		public var dbUtils:DbUtils;
		
		[Inject]
		public var resourceFactory:ResourceFactory;
		
		public function SetupPresenter()
		{
			super(Setup);
		}
		
		override protected function init():void {
			super.init();
			view.displayCharChk.selected = false;
			initFocus();				
		}
		
		public function get view():Setup {
			return this._view as Setup;
		}
		
		override protected function setViewListeners():void {
			registerEventHandler(view.safeKey1, Event.CHANGE, safeToProceed);
			registerEventHandler(view.safeKey2, Event.CHANGE, safeToProceed);
			registerEventHandler(view.safeLocation, Event.CHANGE, safeToProceed);
			registerEventHandler(view.displayCharChk, Event.CHANGE, togglePasswordFields, true);
			registerEventHandler(view.loginSafeButton, MouseEvent.CLICK, gotoLoginView);
			registerEventHandler(view.okButton, MouseEvent.CLICK, createSafe);
			registerEventHandler(view.browseSafe, MouseEvent.CLICK, browseNewSafe);		
		}
		
		private function gotoLoginView():void {
			dispatcher.dispatchEvent(new ApplicationEvent(ApplicationEvent.DISPLAY_LOGIN_VIEW, true));	
		}
		
		public function safeToProceed():void {
			var key1:String = StringUtil.trim(view.safeKey1.text);
			var key2:String = StringUtil.trim(view.safeKey2.text);
			
			view.okButton.enabled = isKeySecure(key1) // first because it updates the label indicating security
				&& bothSafeKeysPresent(key1, key2) 
				&& bothSafeKeysMatch(key1, key2) 
				&& validDBPath();
		}
		
		private function isKeySecure(key1:String):Boolean {							
			// WHEN USING AS3CORELIB EncryptionKeyGenerator
			//The password must be a strong password. 
			//	It must be 8-32 characters long. 
			//	It must contain at least one uppercase letter, 
			//	at least one lowercase letter, 
			//	and at least one number or symbol.				
			var secure:Boolean = loginController.isKeySecure(key1);
			
			view.secureLabel.text = secure ? resourceFactory.getResource("setup.strong") : resourceFactory.getResource("setup.weak");				
			view.secureLabel.setStyle("color", secure ? 0x00FF00 : 0xFF0000);
			return secure;
		}
		
		private function bothSafeKeysPresent(key1:String, key2:String):Boolean {
			return StringUtil.stringHasValue(key1) &&
				   StringUtil.stringHasValue(key2);	
		}
		
		private function bothSafeKeysMatch(key1:String, key2:String):Boolean {
			return key1 == key2;
		}
		
		private function validDBPath():Boolean {
			var dbPath:String = session.dbFilePath;
			return (dbPath.length > AirLockConstants.DB_EXTENSION.length)
					&& dbPath.substr(dbPath.length - AirLockConstants.DB_EXTENSION.length) == AirLockConstants.DB_EXTENSION;
		}
		
		public function togglePasswordFields(event:Event):void {
			var selected:Boolean = CheckBox(event.currentTarget).selected;
			view.safeKey1.displayAsPassword = !selected;
			view.safeKey2.displayAsPassword = !selected;
		}
		
		public function createSafe():void {
			session.safeCombination = StringUtil.trim(view.safeKey1.text);
			safeController.createPasswordDB(session.dbFilePath, session.safeCombination);
			dbUtils.setLastSelectedDB(session.dbFilePath);
			model.selectedView = AirLockConstants.VIEW_MAIN;
		}
		
		[Mediate(event="ApplicationEvent.DISPLAY_SETUP_VIEW")]
		public function displaySetupView():void {	
			if (!StringUtil.stringHasValue(session.dbFilePath)){
				session.dbFilePath = getDefaultFileLocation();
			}	
			model.selectedView = AirLockConstants.VIEW_SETUP;
			
			initFocus();
		}		
		
		private function getDefaultFileLocation():String {
			return File.documentsDirectory.resolvePath(AirLockConstants.DB_FILENAME).nativePath;
		}	
		
		public function browseNewSafe():void {
			// todo: localise
			var safeFile:File = new File(session.dbFilePath);
			safeFile.addEventListener(Event.SELECT, function (event:Event):void {
				var f:File = File(event.target);				
				if (f.extension == null) { f.nativePath += "." +AirLockConstants.DB_EXTENSION; }
				if (f.extension != AirLockConstants.DB_EXTENSION) {
					Alert.show(resourceFactory.getResource("error.extension.caption"), resourceFactory.getResource("error.general.title"));
					return;
				}
				session.dbFilePath = f.nativePath;			
			});
			
			safeFile.browseForSave(resourceFactory.getResource("setup.newsafelocation"));
		}
		
		private function initFocus():void {
			if (view == null || view.safeKey1 == null) return;
			if (view.safeKey1.text.length != 0 && view.safeKey2.text.length != 0)
				view.browseSafe.setFocus();	
			else if (view.safeKey1.text.length == 0)
				view.safeKey1.setFocus();
			else if (view.safeKey2.text.length == 0)
				view.safeKey2.setFocus();	
		}
	}
}